#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <string.h>

#ifndef __SNGEN__
#include "machine.h"
#include "./include/define.h"
#endif

using namespace std;

#include "MD5.h"

inline void MD5_Init(MD5_CTX * pctx)
{
	return CMD5::MD5Init (pctx);
}

inline void MD5_Update(MD5_CTX *context, const char *input, unsigned int inputLen)
{
	return CMD5::MD5Update(context, (unsigned char *)input, inputLen);   
}

inline void MD5_Final(unsigned char digest[16], MD5_CTX *context)
{
	return CMD5::MD5Final(digest, context);
}

#ifdef WIN32 
 int getDiskId (char *hardbuf,int bufsize)
 {
	 return 0;
 }
#else
#include <stdio.h>
#include <sys/ioctl.h>
#include <linux/hdreg.h>
#include <sys/stat.h>
#include <fcntl.h> 
#include <unistd.h> 
#include <net/if.h>
#include <arpa/inet.h>
//#include <openssl/md5.h>


 int getDiskId (char *hardbuf,int bufsize)
{
    int fd;
    struct hd_driveid hid;
    fd = open ("/dev/sda", O_RDONLY);
    if (fd < 0)
    {
        return -1;
    }
    if (ioctl (fd, HDIO_GET_IDENTITY, &hid) < 0)
    {
        return -1;
    }
    close (fd);
    snprintf(hardbuf,bufsize,"%s", hid.serial_no);
    //printf("hdid:%s\n",hardbuf);
	
    return 0;
}


void get_mac(char*mac , char *eth_name)
{
    int  sockfd;
    struct ifreq   ifr;
    char mac_a[6]	={0};
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd == -1) 
    {
        perror("socket error");
    }
    strncpy(ifr.ifr_name, eth_name, IFNAMSIZ);    
    if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) == 0)
    {  
        memcpy(mac_a, ifr.ifr_hwaddr.sa_data, 6);
    }
    sprintf((char*)mac,"%02x%02x%02x%02x%02x%02x", mac_a[0]&0xff, mac_a[1]&0xff, mac_a[2]&0xff, mac_a[3]&0xff, mac_a[4]&0xff, mac_a[5]&0xff);
    //printf("mac:%s\n",mac);
}

#endif

void readContentFromFiles(const char* fileroad ,string &hdinfo)
{
	ifstream in(fileroad);
       getline(in,hdinfo);	
}

int md5(string &hd_to, string &hd_from,char*passwd)
{
	string buf;
#ifdef WIN32
#else
    MD5_CTX ctx;
    string data(hd_from.begin(),hd_from.end());
  for( int k =data.length() /2; k > 0;k=k-1)
    {
        data[k]=data[k]<<k;
    }
    data.append(passwd);
    unsigned char md[16];
    char tmp[3]={0};
    MD5_Init(&ctx);    
    MD5_Update(&ctx,data.c_str(),data.length());   
    MD5_Final(md,&ctx);  
    for( int i=0; i<16; i++ ){
        sprintf(tmp,"%02X",md[i]);
        buf.append(tmp);
    }
#endif
#ifdef __SNGEN__	
	printf("%s\n",buf.c_str());
#endif
    hd_to.append(buf.begin(),buf.end());

	return 1;
}
int confirm_hd( )
{	
	string hdnum;
	string ethName;
	string mac;
	string hdto;
	char hdserialnum[200];
	memset(hdserialnum, 0 ,200);
	getDiskId (hdserialnum,200);
	string  hdfrom(hdserialnum);
	//printf("hd:%s\n",hdfrom.c_str());
#if 0	
	readContentFromFiles("/root/ETPDA2/soft/bin/ethname.txt" ,ethName);
	get_mac( (char*)mac.c_str(), (char*)ethName.c_str());
	hdfrom.append(mac.c_str());
#endif	
	//printf("hd+mac:%s\n",hdfrom.c_str());
	md5(hdto, hdfrom,(char*)"Et3612348");
	readContentFromFiles("/flash/hd.txt" ,hdnum);
	//printf("hdfile:%s\n",hdnum.c_str());
	if(hdnum.compare(hdto) == 0)
	{
		return 1 ;
	}else
	{
		return 0;
	}
	
}


#ifdef WIN32
#define NULL    0
#define EOF    (-1)
#define ERR(s, c)    if(opterr){\
    char errbuf[2];\
    errbuf[0] = c; errbuf[1] = '\n';\
    fputs(argv[0], stderr);\
    fputs(s, stderr);\
fputc(c, stderr);}

int    opterr = 1;
int    optind = 1;
int    optopt;
char   *optarg;
int getopt(int argc, char **argv, char *opts){
    static int sp = 1;
    register int c;
    register char *cp;
    if(sp == 1)
        if(optind >= argc ||
            argv[optind][0] != '-' || argv[optind][1] == '\0')
            return(EOF);
        else if(strcmp(argv[optind], "--") == NULL) {
            optind++;
            return(EOF);
        }
        optopt = c = argv[optind][sp];
        if(c == ':' || (cp=strchr(opts, c)) == NULL) {
            ERR(": illegal option -- ", c);
            if(argv[optind][++sp] == '\0') {
                optind++;
                sp = 1;
            }
            return('?');
        }
        if(*++cp == ':') {
            if(argv[optind][sp+1] != '\0')
                optarg = &argv[optind++][sp+1];
            else if(++optind >= argc) {
                ERR(": option requires an argument -- ", c);
                sp = 1;
                return('?');
            } else
                optarg = argv[optind++];
            sp = 1;
        } else {
            if(argv[optind][++sp] == '\0') {
                sp = 1;
                optind++;
            }
            optarg = NULL;
        }
        return(c);
}


#endif

#ifdef __SNGEN__

int main(int argc, char * argv[])
{
	confirm_hd();
	return 0;
}

#else
//smartx main
int main( int argc, char * argv[] ){
      if (confirm_hd( ) == 1 )
      {
	printf("version 1.0.0.1  copyright @ smartx\n");
	macopt opt;
	memset(&opt,0x00,sizeof(macopt));;
	strcpy(opt.webpath,"./webui");
	strcpy(opt.commsvrip,"0.0.0.0");
	strcpy(opt.websvrip,"0.0.0.0");
	bool sclient = false;
	int c = 0;
	while((c=getopt(argc, argv, "s:w:m:n:x:y:u:"))!=-1){
		switch (c){
			case 's':memset(opt.script,0x00,256);strncpy(opt.script,optarg,strlen(optarg));break;
			case 'u':memset(opt.option,0x00,256);strncpy(opt.option,optarg,strlen(optarg));break;
			case 'w':memset(opt.webpath,0x00,256);strncpy(opt.webpath,optarg,strlen(optarg));break;
			case 'm':memset(opt.commsvrip,0x00,32);strncpy(opt.commsvrip,optarg,strlen(optarg));break;
			case 'n':opt.commsvrport = atoi(optarg);break;
			case 'x':memset(opt.websvrip,0x00,32);strncpy(opt.websvrip,optarg, strlen(optarg));break;
			case 'y':opt.websvrport = atoi(optarg);break;
			case 'c':sclient=true; break;	
			default :break;
		}
	}
	cmachine mac;
	if( !mac.poweron(opt) ){ 
		printf("poweron error! press any key to exit!");
		char sz[64] ={0};
		fgets(sz,64,stdin);
		exit(0);
		return 0;
	}
	while( sclient ){
		Sleep( 1000 );
	}
	while( !sclient ){
		Sleep(1000);
		printf("cmd>");
		char sz[256] ={0};
		fgets(sz,256,stdin);
		int nlen = strlen(sz);
		if(nlen == 1)
			continue;
		mac.execute((char*)sz);
	}
	mac.poweroff();
      	}
   else
   {
 #ifdef WIN32 

#else  	
        //system("bash /etc/init.d/tips.sh");
#endif
   	printf("hd info error,please connect manufacturer!\n");
   }
}
#endif



